package top.kaoshanji.p1ch03a;

import org.apache.hc.core5.http.ContentType;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * 代码清单-p1ch03a-68页a：查找素数
 * URL访问地址：/primeSearcher
 * 没有访问
 * @author kaoshanji
 * ^_^
 * create time 2025/4/3 14:46
 */
public class PrimeSearcher extends HttpServlet implements Runnable {

    long lastprime = 0;  // 最近找到的素数
    Date lastprimeModified = new Date(); // 找到的时间
    Thread searcher;  // 后台搜寻线程

    @Override
    public void init() throws ServletException {
        searcher = new Thread(this);
        searcher.setPriority(Thread.MIN_PRIORITY); // 充分利用系统资源 优先级
        searcher.start();
    }

    @Override
    public void run() {
        long candidate = 1000000000000001L;  // one quadrillion and one

        // Begin loop searching for primes
        while (true) {                       // search forever
            if (isPrime(candidate)) {
                lastprime = candidate;           // new prime
                lastprimeModified = new Date();  // new "prime time"
            }
            candidate += 2;                    // evens aren't prime

            // Between candidates take a 0.2 second break.
            // Another way to be a good citizen with system resources.
            try {
                searcher.sleep(200);
            }
            catch (InterruptedException ignored) { }
        }

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求对象的编码
        req.setCharacterEncoding(StandardCharsets.UTF_8.name());

        // 设置响应对象的编码和内容格式
        resp.setContentType(ContentType.TEXT_PLAIN.toString());
        PrintWriter out = resp.getWriter();

        if (lastprime == 0) {
            out.println("Still searching for first prime...");
        } else {
            out.println("The last prime discovered was " + lastprime);
            out.println(" at " + lastprimeModified);
        }

    }

    @Override
    public void destroy() {
        searcher.stop();
    }

    private static boolean isPrime(long candidate) {
        // Try dividing the number by all odd numbers between 3 and its sqrt
        long sqrt = (long) Math.sqrt(candidate);
        for (long i = 3; i <= sqrt; i += 2) {
            if (candidate % i == 0) return false;  // found a factor
        }

        // Wasn't evenly divisible, so it's prime
        return true;
    }
}
